using System;
using Domain.Dto;
using Domain.Interface;
using Domain.Model;
using Gmmy.DomainExtension;
using Gmmy.Utility;
using Infrastructure.Repository.DataContext;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper.QueryableExtensions;
using Gmmy.RepositoryExtension;
using Gmmy.Utility.Extensions;
using Microsoft.EntityFrameworkCore;
using Surging.Core.Caching;
using Surging.Core.CPlatform.Cache;

namespace Infrastructure.Repository.Repository.Sql
{
    public class ModuleRepository : RepositoryBase<Module>, IModuleRepository
    {

        public ModuleRepository(IDataBaseFactory<EfContext> databaseFactory)
            : base(databaseFactory)
        {

        }

        /// <summary>
        /// 获取功能模块列表
        /// </summary>
        /// <param name="input"></param>
        /// <param name="specification"></param>
        /// <returns></returns>
        public async Task<EntityList<ModuleListDto>> GetList(ModuleListInput input,
            ISpecification<ModuleListInput> specification)
        {
            var result = new EntityList<ModuleListDto>();
            var query = (from a in dbset
                select new ModuleListInput()
                {
                    ID = a.ID,
                    FId = a.FId,
                    ModuleName = a.ModuleName,
                    Sort = a.Sort,
                    CreateTime = a.CreateTime,
                    IsDeleted = a.IsDeleted,

                }).Where(specification.SatisfiedBy());
            if (input.OrderParm == null || !input.OrderParm.Any())
            {
                input.OrderParm = new Dictionary<string, string> {{"Sort", "ASC"}};
            }
            query = DataSort(query, input.OrderParm);
            var data = await FindAllAsyncAsQuery(query, input.PageIndex, input.PageSize);
            if (data.Data.Any())
            {
                result = data.MapTo<EntityList<ModuleListDto>, EntityList<ModuleListInput>>();
            }
            return result;
        }

        /// <summary>
        /// 获取功能详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<ModuleDto> GetModule(Guid id)
        {
            return await (from a in dbset.Where(x => !x.IsDeleted && x.ID == id)
                let action =
                    (from b in DataContext.Set<ModuleAction>().Where(x => !x.IsDeleted && x.ModuleId == a.ID).OrderBy(x => x.Sort) select b)
                select new ModuleDto
                {
                    ID = a.ID,
                    FId = a.FId,
                    ModuleName = a.ModuleName,
                    Sort = a.Sort,
                    ActionList = action.Select(x => new ModuleActionDto
                    {
                        ID = x.ID,
                        Name = x.ActionName,
                        Sort = x.Sort,
                        ApiAddress = x.ActionAddress
                    })
                }).FirstOrDefaultAsync();
        }

        /// <summary>
        /// 获取所有模块
        /// </summary>
        /// <returns></returns>
        public async Task<List<ModuleDto>> GetModuleAll()
        {
            var allModules = 
                (await GetManyAsync(new DirectSpecification<Module>(x => !x.IsDeleted), true)).Select(x => new ModuleDto
            {
                ID = x.ID,
                FId = x.FId,
                ModuleName = x.ModuleName,
                Sort = x.Sort
            }).ToList();
            var allActions =
                await (from a in DataContext.Set<ModuleAction>().Where(x => !x.IsDeleted)
                select new ModuleActionDto
                {
                    ID = a.ID,
                    ModuleId = a.ModuleId,
                    Name = a.ActionName,
                    Sort = a.Sort,
                    ApiAddress = a.ActionAddress
                }).ToListAsync();
            return LoadModules(allModules, allActions, Guid.Empty);
        }
        /// <summary>
        /// 装载模块
        /// </summary>
        /// <param name="moduleTemplate"></param>
        /// <param name="actionTemplate"></param>
        /// <param name="fid"></param>
        /// <returns></returns>
        List<ModuleDto> LoadModules(List<ModuleDto> moduleTemplate, List<ModuleActionDto> actionTemplate, Guid fid)
        {
            var result=new List<ModuleDto>();
            result.AddRange(moduleTemplate.Where(x => x.FId == fid).OrderBy(y => y.Sort));
            result.ForEach(x =>
            {
                x.ActionList = actionTemplate.Where(y => y.ModuleId == x.ID).OrderBy(y => y.Sort);
                x.ChildModuleList = LoadModules(moduleTemplate, actionTemplate, x.ID);
            });
            return result;
        }

        /// <summary>
        /// 获取所有模块功能地址
        /// </summary>
        /// <returns></returns>
        public async Task<List<string>> GetModuleAddressAll()
        {
            var query = (from a in DataContext.Set<ModuleAction>().Where(x => !x.IsDeleted)
                join b in DataContext.Set<Module>().Where(x => !x.IsDeleted) on a.ModuleId equals b.ID
                select a.ActionAddress
            );
            return await query.ToListAsync();
        }
    }
}